/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package neuronalenetzeelearning.view.controlpanel;

import java.awt.BorderLayout;
import neuronalenetzeelearning.view.gui.*;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.LinkedList;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
import neuronalenetzeelearning.model.Graph;
import neuronalenetzeelearning.model.Matrix;
import neuronalenetzeelearning.view.help.HelpPanel;
import neuronalenetzeelearning.view.help.HelpWindowFactory;
import neuronalenetzeelearning.view.mathoutput.MathOutputComponent;

/**
 *
 * @author Henning
 */
public class StepwisePanel extends GraphPanelProperty {

    JPanel matrixPanel;
    JLabel stepLabel;
    JButton saveButton;
    LinkedList<Matrix>matrixList = new LinkedList<Matrix>();
    JFileChooser fc;
    int stepcount =0;
    JPanel InputVectorPanel, TargetVectorPanel, InputPanel, OutputPanel;

    
    public StepwisePanel(){

        super();
        this.setBackground(background);
        this.setLayout(grid);
        this.setBorder(javax.swing.BorderFactory.createTitledBorder("Option: Das Netz Schritteweise lernen lassen (n == 1)"));

        //Set the look and feel
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
        }
        constraints.gridwidth = GridBagConstraints.REMAINDER;
        constraints.gridx = 1;
        constraints.gridy = 1;

        JLabel bord = new JLabel("------------------------------------------------------------------------------------------------------------------");
        add(bord, constraints);

        constraints.gridwidth = GridBagConstraints.RELATIVE;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.gridheight = 1;
        constraints.gridx = 1;
        constraints.gridy = 2;

        InputVectorPanel = new JPanel();
        InputVectorPanel.setLayout(new BorderLayout());
        // Layout neu definieren.
        InputVectorPanel.setBackground(background);
        InputVectorPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Eingabevektoren"));

        InputVectorPanel.add(new JTable(), BorderLayout.CENTER);
        add(InputVectorPanel, constraints);

        constraints.gridwidth = GridBagConstraints.RELATIVE;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.gridheight = 1;
        constraints.gridx = 2;
        constraints.gridy = 2;

        InputPanel = new JPanel();
        InputPanel.setLayout(new BorderLayout());
        // Layout neu definieren.
        InputPanel.setBackground(background);
        InputPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Eingabe"));

        InputPanel.add(new JTable(), BorderLayout.CENTER);
        add(InputPanel, constraints);

        constraints.gridwidth = GridBagConstraints.RELATIVE;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.gridheight = 1;
        constraints.gridx = 1;
        constraints.gridy = 3;

        TargetVectorPanel = new JPanel();
        TargetVectorPanel.setLayout(new BorderLayout());
        // Layout neu definieren.
        TargetVectorPanel.setBackground(background);
        TargetVectorPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Zielvektoren"));

        TargetVectorPanel.add(new JTable(), BorderLayout.CENTER);
        TargetVectorPanel.setVisible(false);//Visibly-state gets changed in case of supervised learning
        add(TargetVectorPanel, constraints);

        constraints.gridwidth = GridBagConstraints.RELATIVE;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.gridheight = 1;
        constraints.gridx = 2;
        constraints.gridy = 3;

        OutputPanel = new JPanel();
        OutputPanel.setLayout(new BorderLayout());
        // Layout neu definieren.
        OutputPanel.setBackground(background);
        OutputPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Ausgabe"));

        OutputPanel.add(new JTable(), BorderLayout.CENTER);
        OutputPanel.setVisible(false);//Visibly-state gets changed in case of supervised learning
        add(OutputPanel, constraints);

        constraints.gridwidth = GridBagConstraints.REMAINDER;
        constraints.gridx = 1;
        constraints.gridy = 4;

        matrix = new MathOutputComponent(graph.getWeightMatrix());
        matrix.setHAlign("center");

        matrixPanel = new JPanel();
        matrixPanel.setLayout(new BorderLayout());
        // Layout neu definieren.
        matrixPanel.setBackground(background);
        matrixPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Gewichtsmatrix"));
        matrixPanel.add(matrix, BorderLayout.CENTER);
        this.add(matrixPanel, constraints);

        constraints.gridwidth = GridBagConstraints.RELATIVE;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.gridx = 1;
        constraints.gridy = 5;

        this.add(new JLabel("aktueller Schritt"), constraints);

        constraints.gridwidth = GridBagConstraints.RELATIVE;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.gridx = 2;
        constraints.gridy = 5;

        stepLabel = new JLabel("0");
        stepLabel.setHorizontalAlignment(JLabel.CENTER);
        add(stepLabel, constraints);

        constraints.gridwidth = GridBagConstraints.RELATIVE;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.gridx = 1;
        constraints.gridy = 6;

        JLabel StepLabel = new JLabel("Bitte wählen Sie einen Speicherort für die errechneten Matrizen.");
        add(StepLabel, constraints);

        constraints.gridwidth = GridBagConstraints.RELATIVE;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.gridx = 2;
        constraints.gridy = 6;

        saveButton = new JButton("Speichern");
        fc = new JFileChooser();
        fc.addChoosableFileFilter(new MyFilter());

        saveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == saveButton) {
                    fc.showSaveDialog(getPanel());
                    File file = fc.getSelectedFile();
                    path = file.getAbsolutePath();
                    if (!path.contains(".")){
                       System.out.println(fc.getFileFilter().getDescription());
                       path+=fc.getFileFilter().getDescription().substring(1);
                    }
                    System.out.println(path);
                }
            }
        });
        add(saveButton, constraints);

        constraints.gridwidth = GridBagConstraints.RELATIVE;
        constraints.fill = GridBagConstraints.HORIZONTAL;

        navigation.add(previous, constraints);
        navigation.add(getHelpButton(), constraints);
        navigation.add(start, constraints);

        constraints.gridwidth = GridBagConstraints.REMAINDER;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.gridx = 1;
        constraints.gridy = 7;

        this.add(navigation, constraints);

        this.setVisible(true);
    }

    public static void main(String[] args) {
        JFrame test = new JFrame();
        test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        test.setPreferredSize(new Dimension(800, 800));

        Graph graph = new Graph();
        test.add(new StepwisePanel());

        test.setResizable(false);
        test.pack();
        test.setVisible(true);
    }

    @Override
    public void setGraph(Graph graph) {
        this.graph = graph;
    }
     public LinkedList<Matrix> getMatrixList(){
        return this.matrixList;
    }

    @Override
    public int getStep(){
        int zahl = Integer.parseInt(this.stepLabel.getText());
        return zahl;
    }

    public JPanel getPanel(){
        return this;
    }
    @Override
    public Vector<Double> getVector(){
        Vector <Double>Inputvector = new Vector<Double>();
        for (int i  =0; i< graph.getLayer1Nodes().size(); i++){
            graph.getLayer1Nodes().get(i).getInputValue();
            Inputvector.add(graph.getLayer1Nodes().get(i).getInputValue());
        }
        return Inputvector;
    }

    @Override
    public void setInputVectorPanel(JTable inputVectorTable){
        inputVectorTable.setEnabled(false);
        this.InputVectorPanel.add(inputVectorTable);
        this.InputVectorPanel.repaint();
        this.repaint();
    }
   @Override
    public void setTargetVectorPanel(JTable targetVectorTable){
        targetVectorTable.setEnabled(false);
        this.TargetVectorPanel.add(targetVectorTable);
        this.TargetVectorPanel.setVisible(true);
        this.TargetVectorPanel.repaint();
        this.repaint();
    }
   /**
    * Hier wird, je nach Lernregel, der Zielvektor angezeigt ebenso wie die Ausgabe
    * @param panel
    */
   @Override
    public void setOutputVectorPanel(JPanel panel){
       if (panel instanceof LearningRuleSuperwisedLearningPanel){
           this.OutputPanel.setVisible(true);
           this.TargetVectorPanel.setVisible(true);
           this.OutputPanel.repaint();
           this.repaint();
       }
       else{
           this.OutputPanel.setVisible(true);
           this.TargetVectorPanel.setVisible(false);
           this.OutputPanel.repaint();
           this.repaint();
       }
        
    }

   public void updateIOComponent(Graph graph){
       JTable inputTable = new JTable();
       JTable outputTable = new JTable();

       DefaultTableModel inputModel = new DefaultTableModel();
       DefaultTableModel outputModel = new DefaultTableModel();

       inputModel.setColumnCount(1);
       inputModel.setRowCount(graph.getLayer1Nodes().size());
       for (int i = 0; i < graph.getLayer1Nodes().size(); i++){
           inputModel.setValueAt(graph.getLayer1Nodes().elementAt(i).getInputValue(), i, 0);
       }
       outputModel.setColumnCount(1);
       outputModel.setRowCount(graph.getLayer2Nodes().size());
       for (int i = 0; i < graph.getLayer2Nodes().size(); i++){
           outputModel.setValueAt(graph.getLayer2Nodes().elementAt(i).getOutputValue(), i, 0);
       }

       inputTable.setModel(inputModel);
       outputTable.setModel(outputModel);

       this.InputPanel.removeAll();
       this.InputPanel.add(inputTable);
       this.InputPanel.repaint();
       this.InputPanel.validate();

       this.OutputPanel.removeAll();
       this.OutputPanel.add(outputTable);
       this.OutputPanel.repaint();
       this.OutputPanel.validate();

       for (int i = 0; i < graph.getLayer2Nodes().size(); i++){
           System.out.println(graph.getLayer2Nodes().get(i).getOutputValue());
       }

   }

    public void updateMatrixComponent(Graph graph) {
        this.matrix.updateMatrix(graph.getWeightMatrix());
        matrixList.add(graph.getWeightMatrix());
    }

    public void updateMatrixComponent(Graph graph, LinkedList<String>propertys) {
        this.matrix.updateMatrix(graph.getWeightMatrix());
        matrixList.add(graph.getWeightMatrix());
        this.matrix.printMatrixToFile(graph.getWeightMatrix(), path, getStep(),getVector(), propertys);
        this.matrixPanel.repaint();
        this.matrixPanel.validate();
    }

    public void updateJLabelstep(int step){
        this.stepLabel.setText(""+step);
    }
    class MyFilter extends javax.swing.filechooser.FileFilter {
    @Override
    public boolean accept(File file) {
        String filename = file.getName();
        return filename.endsWith(".txt");
    }
    @Override
    public String getDescription() {
        return "*.txt";
    }
    //Input vector Graph->Layer1Node->getValue
}

//            @Override
//    public ActionListener getActionListener() {
//        return new ActionListener() {
//
//            @Override
//            public void actionPerformed(ActionEvent e) {
//                System.out.println("Help from Learning Rule Chooser Panel");
//            }
//        };
//
//    }

            @Override
    public ActionListener getActionListener() {
        return new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                HelpWindowFactory.createHelpWindow(new HelpPanel("src/neuronalenetzeelearning/view/help/resources/Speichern.png"));
            }
        };

    }
}
